package com.example.baselibrary.utlis

import android.content.Context
import android.content.Intent
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.os.Build
import android.provider.Settings
import android.text.TextUtils
import android.util.DisplayMetrics
import android.view.WindowManager
import java.security.SecureRandom
import java.util.UUID
import kotlin.text.isEmpty
import kotlin.text.replace
import kotlin.text.substring
import kotlin.text.toRegex
import kotlin.text.toUpperCase

/**
 * 应用与设备信息工具类
 * 提供应用版本信息和设备详细信息的获取功能
 */
class AppInfoUtil private constructor() {
    init {
        throw UnsupportedOperationException("工具类不允许实例化")
    }

    companion object {
        // region 应用信息相关方法
        /**
         * 获取应用版本名称
         *
         * @param context 上下文
         * @return 版本名称，获取失败返回null
         */
        fun getVersionName(context: Context): String? {
            val info: PackageInfo? = getPackageInfo(context)
            return if (info != null) info.versionName else null
        }

        /**
         * 获取应用版本号
         *
         * @param context 上下文
         * @return 版本号，获取失败返回0
         */
        fun getVersionCode(context: Context): Long {
            val info: PackageInfo? = getPackageInfo(context)
            if (info != null) {
                return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) info.getLongVersionCode() else info.versionCode.toLong()
            }
            return 0
        }

        /**
         * 获取应用包信息
         *
         * @param context 上下文
         * @return PackageInfo对象，获取失败返回null
         */
        private fun getPackageInfo(context: Context): PackageInfo? {
            try {
                return context.getPackageManager()
                    .getPackageInfo(context.getPackageName(), 0)
            } catch (e: PackageManager.NameNotFoundException) {
                return null
            }
        }

        // endregion
        // region 应用安装与启动
        /**
         * 判断指定包名的应用是否已安装
         *
         * @param context     上下文
         * @param packageName 包名
         * @return true: 已安装, false: 未安装或包名为空
         */
        fun isAppInstalled(context: Context, packageName: String?): Boolean {
            if (TextUtils.isEmpty(packageName)) {
                return false
            }
            try {
                context.getPackageManager().getPackageInfo(packageName!!, 0)
                return true
            } catch (e: PackageManager.NameNotFoundException) {
                return false
            }
        }

        /**
         * 启动指定包名的应用
         *
         * @param context     上下文
         * @param packageName 包名
         * @return true: 启动成功, false: 启动失败
         */
        fun launchApp(context: Context, packageName: String): Boolean {
            try {
                val intent = context.getPackageManager()
                    .getLaunchIntentForPackage(packageName)
                if (intent != null) {
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    context.startActivity(intent)
                    return true
                }
            } catch (e: Exception) {
                // 忽略所有异常，返回false
            }
            return false
        }

        // endregion
        // region 设备信息获取
        val deviceInfo: String
            /**
             * 获取设备制造商和型号
             *
             * @return 设备信息字符串，格式: "厂商 型号"
             */
            get() = "设备厂商：" + Build.MANUFACTURER + "    设备型号： " + Build.MODEL

        /**
         * 获取安全的设备标识符
         *
         * @return 优先返回 ANDROID_ID，不可用时生成应用级唯一ID并存储
         */
        /**
         * 获取安全的设备标识符
         *
         * @return 优先返回有效的ANDROID_ID，否则返回固定格式的唯一值 (0000-0000-0000)
         */
        fun getSafeDeviceId(context: Context): String {
            // 默认固定值（符合0000-0000-0000格式）
            val FALLBACK_ID = "0000-0000-0000"

            try {
                // 尝试获取ANDROID_ID
                val androidId = Settings.Secure.getString(
                    context.getContentResolver(),
                    Settings.Secure.ANDROID_ID
                )

                // 验证有效性（非空且不是已知问题值）
                if (!TextUtils.isEmpty(androidId) && ("9774d56d682e549c" != androidId) && ("0000000000000000" != androidId)) {
                    return formatDeviceId(androidId!!)
                }

                // 获取或生成应用级ID
                val appScopedId: String = getOrCreateAppScopedId(context)
                return formatDeviceId(appScopedId)
            } catch (e: Exception) {
                LogUtils.logEvent("获取设备号失败，用随机数代替" + e)
                return FALLBACK_ID // 确保永远有返回值
            }
        }


        /**
         * 获取或创建应用级唯一ID
         */
        private fun getOrCreateAppScopedId(context: Context): String {
            val prefs = context.getSharedPreferences(
                "device_id_prefs", Context.MODE_PRIVATE
            )

            // 尝试从SharedPreferences获取
            var storedId = prefs.getString("app_scoped_id", null)

            if (storedId == null) {
                // 生成新的UUID并存储
                storedId = UUID.randomUUID().toString().replace("-", "").substring(0, 12)
                //判断获取到的值是否为空
                if (storedId.isEmpty()) {
                    LogUtils.logEvent("UUID生成设备ID为空，使用SecureRandom兜底")
                    val charPool = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
                    val secureRandom = SecureRandom()

                    val builder = StringBuilder()
                    repeat(12) {
                        builder.append(charPool[secureRandom.nextInt(charPool.length)])
                    }
                    storedId = builder.toString()
                }
                prefs.edit().putString("app_scoped_id", storedId).apply()
            }

            return storedId
        }

        /**
         * 格式化ID为0000-0000-0000格式
         */
        private fun formatDeviceId(rawId: String): String {
            // 清理输入（只保留字母数字）
            val cleanId = rawId.replace("[^a-zA-Z0-9]".toRegex(), "")

            // 确保长度至少为12（不足补0，超长截取）
            val normalized = (cleanId + "000000000000").substring(0, 12)

            // 格式化为0000-0000-0000
            return StringBuilder()
                .append(normalized.substring(0, 4)).append("-")
                .append(normalized.substring(4, 8)).append("-")
                .append(normalized.substring(8, 12))
                .toString()
                .toUpperCase()
        }

        /**
         * 获取屏幕分辨率
         *
         * @param context 上下文
         * @return 屏幕分辨率字符串，格式: "宽度x高度"
         */
        fun getScreenResolution(context: Context): String {
            val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
            val display = wm.getDefaultDisplay()
            val metrics = DisplayMetrics()
            display.getMetrics(metrics)
            return metrics.widthPixels.toString() + "x" + metrics.heightPixels
        }

        /**
         * 获取屏幕密度DPI
         *
         * @param context 上下文
         * @return 屏幕密度DPI
         */
        fun getScreenDensity(context: Context): Int {
            return context.getResources().getDisplayMetrics().densityDpi
        }

        /**
         * 判断设备是否是平板
         *
         * @param context 上下文
         * @return true: 平板, false: 手机
         */
        fun isTablet(context: Context): Boolean {
            return ((context.getResources().getConfiguration().screenLayout
                    and Configuration.SCREENLAYOUT_SIZE_MASK)
                    >= Configuration.SCREENLAYOUT_SIZE_LARGE)
        }

        val osVersion: String
            /**
             * 获取系统版本信息
             *
             * @return 系统版本字符串，格式: "Android 版本号(API级别)"
             */
            get() = "Android版本 " + Build.VERSION.RELEASE + " (API " + Build.VERSION.SDK_INT + ")" // endregion
    }
}